﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace CLEXA.DataContracts
{
    [DataContract]
    public class HistogramRowData
    {
        private static readonly IEqualityComparer<HistogramRowData> valueComparer = new HistogramRowDataValueComparer();
        [DataMember]
        private readonly string group;
        [DataMember]
        private readonly List<double> values;
        private ReadOnlyCollection<double> valuesReadOnly;

        public static IEqualityComparer<HistogramRowData> ValueComparer
        {
            get { return HistogramRowData.valueComparer; }
        } 

        public string Group
        {
            get { return group; }
        }

        public ReadOnlyCollection<double> Values
        {
            get
            {
                if (valuesReadOnly == null)
                {
                    valuesReadOnly = new ReadOnlyCollection<double>(values);
                }
                return valuesReadOnly;
            }
        }

        public HistogramRowData(string group, IEnumerable<double> values)
        {
            this.group = group;
            this.values = values.ToList();
        }

        public override string ToString()
        {
            string v = "[";
            for (int i = 0; i < Values.Count; i++)
            {
                if (i != 0)
                {
                    v += ", ";
                }
                v += Values[i].ToString();
            }
            v += "]";
            return string.Format("Group: {0}, Values: {1}", Group, v);
        }

        private sealed class HistogramRowDataValueComparer : IEqualityComparer<HistogramRowData>
        {
            public bool Equals(HistogramRowData x, HistogramRowData y)
            {
                if (Object.ReferenceEquals(x, y))
                {
                    return true;
                }
                if (Object.ReferenceEquals(x, null))
                {
                    return false;
                }
                if (Object.ReferenceEquals(y, null))
                {
                    return false;
                }

                return x.Group == y.Group && x.Values.SequenceEqual(y.Values);
            }

            public int GetHashCode(HistogramRowData obj)
            {
                if (obj == null)
                {
                    return 0;
                }
                else
                {
                    int hash = obj.Group.GetHashCode();
                    foreach (double value in obj.Values)
                    {
                        hash ^= value.GetHashCode();
                    }
                    return hash;
                }
            }
        }
    }
}
